package core

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"strconv"
	"time"
	"tone-agent/entity"

	"github.com/spf13/viper"
)

func WriteHeartbeat() {
	timestamp := time.Now().Unix()
	timestampStr := strconv.FormatInt(timestamp, 10)
	file := fmt.Sprintf("%s/.heartbeat", entity.LogPath)
	if err := WriteFile(file, []byte(timestampStr), 0644); err != nil {
		MyLogger.WithFields(LogFields{"error": err.Error()}).Error("Write heartbeat to file failed!")
		return
	}
}

func SyncHeartbeat() error {
	if viper.Get(entity.TSNConfigKey) == nil || viper.Get(entity.ProxyConfigKey) == nil {
		configYaml := fmt.Sprintf("%s/%s.yaml", entity.ConfigPath, entity.APPName)
		MyLogger.WithFields(LogFields{"config_file": configYaml}).Info("tsn or proxy not configured")
		return errors.New("tsn not configured")
	}
	url := fmt.Sprintf("%s/%s", viper.Get(entity.ProxyConfigKey), entity.HeartbeatAPI)
	tsn := viper.GetString("tsn")
	sign := GetSign()
	data := map[string]string{
		"tsn":    tsn,
		"sign":   sign,
		"ip":     GetLocalIP(),
		"arch":   ExecCommand("arch"),
		"kernel": ExecCommand("uname", "-r"),
		"distro": ExecCommand("cat", "/etc/os-release"),
	}
	bytesData, _ := json.Marshal(data)
	client := GetHttpClient()
	resp, err := client.Post(url, "application/json", bytes.NewBuffer(bytesData))
	if resp != nil {
		defer resp.Body.Close()
	}
	if err != nil {
		MyLogger.WithFields(LogFields{"error": err.Error(), "tsn": tsn}).Error("Send heartbeat to proxy failed!")
		return err
	}
	if resp.StatusCode != 200 {
		MyLogger.WithFields(LogFields{"StatusCode": resp.StatusCode, "tsn": tsn}).Info("Send heartbeat to proxy failed!")
		return err
	}
	result := make(map[string]string)
	resBytes, err2 := io.ReadAll(resp.Body)
	if err2 != nil {
		MyLogger.WithFields(LogFields{"error": err2.Error(), "tsn": tsn}).Error("Send heartbeat to proxy failed!")
		return err2
	}
	json.Unmarshal(resBytes, &result)
	if result["SUCCESS"] != "TRUE" {
		MyLogger.WithFields(LogFields{"error": result, "tsn": tsn}).Error("Send heartbeat to proxy failed!")
		return errors.New(result["ERROR_MSG"])
	}
	return nil
}
